import React, { useState, useCallback, useEffect, useRef } from 'react';
import { Upload, message, Progress } from 'antd';
import { UploadOutlined, DeleteOutlined, EyeOutlined } from '@ant-design/icons';
import type { UploadFile, UploadProps } from 'antd/es/upload/interface';
import type { RcFile } from 'antd/es/upload';

interface ImageUploaderProps {
  /** 最大上传数量 */
  maxCount?: number;
  /** 是否支持多选 */
  multiple?: boolean;
  /** 文件大小限制（MB） */
  maxSize?: number;
  /** 已上传的图片列表 */
  value?: UploadFile[];
  /** 图片上传变化回调 */
  onChange?: (files: UploadFile[]) => void;
  /** 上传接口URL */
  action?: string;
  /** 自定义上传处理 */
  customRequest?: (options: any) => void;
  /** 是否禁用 */
  disabled?: boolean;
  /** 提示文本 */
  placeholder?: string;
}

/**
 * 图片上传组件
 * 支持拖拽上传、图片预览、上传进度显示
 */
const ImageUploader: React.FC<ImageUploaderProps> = ({
  maxCount = 5,
  multiple = true,
  maxSize = 5,
  value = [],
  onChange,
  action = '/api/upload',
  customRequest,
  disabled = false,
  placeholder = ''
}) => {
  const [fileList, setFileList] = useState<UploadFile[]>(value);
  const [uploading, setUploading] = useState(false);
  const [dragging, setDragging] = useState(false);
  const uploaderRef = useRef<HTMLDivElement>(null);
  const dragAreaRef = useRef<HTMLDivElement>(null);

  // 处理窗口级别的拖拽事件
  useEffect(() => {
    const handleWindowDragEnter = (e: DragEvent) => {
      if (disabled || !dragAreaRef.current) return;
      
      e.preventDefault();
      e.stopPropagation();
      
      // 检查是否拖拽的是文件
      if (e.dataTransfer && e.dataTransfer.items && e.dataTransfer.items.length > 0) {
        let hasFile = false;
        for (let i = 0; i < e.dataTransfer.items.length; i++) {
          if (e.dataTransfer.items[i].kind === 'file') {
            hasFile = true;
            break;
          }
        }
        
        if (hasFile) {
          // 检查鼠标位置是否在真正的拖拽区域内
          const rect = dragAreaRef.current.getBoundingClientRect();
          const x = e.clientX;
          const y = e.clientY;
          
          if (x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom) {
            setDragging(true);
          }
        }
      } else if (e.dataTransfer && e.dataTransfer.types.includes('Files')) {
        // 检查鼠标位置是否在真正的拖拽区域内
        const rect = dragAreaRef.current.getBoundingClientRect();
        const x = e.clientX;
        const y = e.clientY;
        
        if (x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom) {
          setDragging(true);
        }
      }
    };

    const handleWindowDragOver = (e: DragEvent) => {
      if (disabled || !dragAreaRef.current) return;
      
      e.preventDefault();
      e.stopPropagation();
      
      // 设置正确的拖拽效果
      if (e.dataTransfer) {
        e.dataTransfer.dropEffect = 'copy';
      }
      
      // 持续检查鼠标位置是否在真正的拖拽区域内
      const rect = dragAreaRef.current.getBoundingClientRect();
      const x = e.clientX;
      const y = e.clientY;
      
      if (x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom) {
        // 如果鼠标在真正的拖拽区域内，保持拖拽状态
        if (!dragging) {
          setDragging(true);
        }
      } else {
        // 如果鼠标不在真正的拖拽区域内，取消拖拽状态
        if (dragging) {
          setDragging(false);
        }
      }
    };

    const handleWindowDragLeave = (e: DragEvent) => {
      if (disabled || !dragAreaRef.current) return;
      
      e.preventDefault();
      e.stopPropagation();
      
      // 检查鼠标是否离开了真正的拖拽区域
      const rect = dragAreaRef.current.getBoundingClientRect();
      const x = e.clientX;
      const y = e.clientY;
      
      // 如果鼠标离开了拖拽区域，则取消拖拽状态
      if (x < rect.left || x > rect.right || y < rect.top || y > rect.bottom) {
        setDragging(false);
      }
    };

    const handleWindowDrop = (e: DragEvent) => {
      if (disabled || !dragAreaRef.current) return;
      
      e.preventDefault();
      e.stopPropagation();
      
      // 检查是否在真正的拖拽区域内释放文件
      const rect = dragAreaRef.current.getBoundingClientRect();
      const x = e.clientX;
      const y = e.clientY;
      
      if (x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom) {
        // 只在真正的拖拽区域内释放文件时，才取消拖拽状态
        setDragging(false);
      }
    };

    const handleWindowDragEnd = () => {
      setDragging(false);
    };

    window.addEventListener('dragenter', handleWindowDragEnter);
    window.addEventListener('dragover', handleWindowDragOver);
    window.addEventListener('dragleave', handleWindowDragLeave);
    window.addEventListener('drop', handleWindowDrop);
    window.addEventListener('dragend', handleWindowDragEnd);

    return () => {
      window.removeEventListener('dragenter', handleWindowDragEnter);
      window.removeEventListener('dragover', handleWindowDragOver);
      window.removeEventListener('dragleave', handleWindowDragLeave);
      window.removeEventListener('drop', handleWindowDrop);
      window.removeEventListener('dragend', handleWindowDragEnd);
    };
  }, [disabled, dragging]);

  // 处理文件列表变化
  const handleChange: UploadProps['onChange'] = useCallback(({ fileList: newFileList }: { fileList: UploadFile[] }) => {
    const updatedFileList = newFileList.map(file => {
      if (file.status === 'done') {
        return {
          ...file,
          url: file.response?.url || file.url,
          thumbUrl: file.response?.thumbUrl || file.thumbUrl,
        };
      }
      return file;
    });

    setFileList(updatedFileList);
    onChange?.(updatedFileList);
  }, [onChange]);

  // 自定义上传处理
  const handleCustomRequest = useCallback(async (options: any) => {
    const { file, onProgress, onSuccess, onError } = options;
    
    if (customRequest) {
      customRequest(options);
      return;
    }

    try {
      setUploading(true);
      
      // 模拟上传过程
      const formData = new FormData();
      formData.append('file', file);

      // 这里应该调用真实的上传API
      // const response = await fetch(action, {
      //   method: 'POST',
      //   body: formData,
      // });
      
      // 模拟上传进度
      let progress = 0;
      const interval = setInterval(() => {
        progress += 10;
        onProgress?.({ percent: progress });
        
        if (progress >= 100) {
          clearInterval(interval);
          onSuccess?.({
            url: URL.createObjectURL(file),
            thumbUrl: URL.createObjectURL(file),
            name: file.name,
            size: file.size,
          });
          setUploading(false);
        }
      }, 100);

    } catch (error) {
      onError?.(error as Error);
      setUploading(false);
    }
  }, [action, customRequest]);

  // 文件上传前验证
  const beforeUpload = useCallback((file: RcFile) => {
    const isImage = file.type.startsWith('image/');
    if (!isImage) {
      message.error('只能上传图片文件！');
      return false;
    }

    const isLtMaxSize = file.size / 1024 / 1024 < maxSize;
    if (!isLtMaxSize) {
      message.error(`图片大小不能超过 ${maxSize}MB！`);
      return false;
    }

    if (fileList.length >= maxCount) {
      message.error(`最多只能上传 ${maxCount} 张图片！`);
      return false;
    }

    return true;
  }, [maxSize, maxCount, fileList.length]);

  // 删除图片
  const handleRemove = useCallback((file: UploadFile) => {
    const newFileList = fileList.filter(item => item.uid !== file.uid);
    setFileList(newFileList);
    onChange?.(newFileList);
  }, [fileList, onChange]);

  // 预览图片
  const handlePreview = useCallback(async (file: UploadFile) => {
    if (!file.url && !file.preview) {
      file.preview = await getBase64(file.originFileObj as RcFile);
    }

    // 自定义预览实现
    const modal = document.createElement('div');
    modal.style.cssText = `
      position: fixed; top: 0; left: 0; width: 100%; height: 100%; 
      background: rgba(0,0,0,0.8); z-index: 9999; display: flex; 
      align-items: center; justify-content: center;
    `;
    
    const img = document.createElement('img');
    img.src = file.url || file.preview || '';
    img.style.cssText = 'max-width: 90%; max-height: 90%; object-fit: contain;';
    
    modal.appendChild(img);
    modal.onclick = () => document.body.removeChild(modal);
    document.body.appendChild(modal);
  }, []);

  // 获取图片base64
  const getBase64 = (file: RcFile): Promise<string> =>
    new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.readAsDataURL(file);
      reader.onload = () => resolve(reader.result as string);
      reader.onerror = error => reject(error);
    });

  const uploadProps: UploadProps = {
    fileList,
    onChange: handleChange,
    beforeUpload,
    customRequest: handleCustomRequest,
    onRemove: handleRemove,
    onPreview: handlePreview,
    listType: 'picture-card' as const,
    multiple,
    disabled: disabled || uploading,
    accept: 'image/*',
    showUploadList: {
      showPreviewIcon: true,
      showRemoveIcon: true,
    },
    action: action,
    className: 'w-full',
    style: {
      border: 'none',
      backgroundColor: 'transparent',
    },
  };

  return (
    <div 
      ref={uploaderRef}
      className="image-uploader"
    >
      <Upload {...uploadProps}>
        {fileList.length >= maxCount ? null : (
          <div 
            ref={dragAreaRef}
            className={`flex flex-col items-center justify-center p-6 h-full transition-all duration-200 rounded-lg border-2 border-dashed ${
              dragging 
                ? 'border-blue-500 bg-blue-50' 
                : 'border-gray-300 bg-gray-50 hover:border-gray-400 hover:bg-gray-100'
            }`}
          >
            <div className={`text-xs ${
              dragging ? 'text-blue-600' : 'text-gray-600'
            }`}>
              {dragging ? '释放以上传' : placeholder || '点击或拖拽上传'}
            </div>
          </div>
        )}
      </Upload>
      
      {/* 上传进度显示 */}
      {uploading && (
        <div className="mt-4">
          <div className="text-sm font-medium">上传进度: {fileList.find(file => file.status === 'uploading')?.percent || 0}%</div>
          <div className="text-xs text-gray-500 mt-1 text-center">
            正在上传图片...
          </div>
        </div>
      )}
      
      {/* 错误提示 */}
      {fileList.some(file => file.status === 'error') && (
        <div className="mt-3 text-red-500 text-sm">
          部分图片上传失败，请检查后重试
        </div>
      )}
      
      {/* 添加样式修复 */}
      <style>
        {`
          .ant-upload-list-item-actions {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(0%, -50%) !important;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 4px;
          }
        `}
      </style>
    </div>
  );
};

export default ImageUploader;